/*
 * Created by JFormDesigner on Thu Nov 12 17:12:47 CET 2009
 */

package at.jku.pervasive.gui.jformdesigner;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import at.jku.pervasive.Application;
import at.jku.pervasive.Measurement;
import at.jku.pervasive.Position;
import at.jku.pervasive.TagAssignment;
import at.jku.pervasive.TagPositionListener;
import at.jku.pervasive.gui.action.RecordAction;
import at.jku.pervasive.simulator.StepwiseFileServerSimulator;

import com.jgoodies.forms.factories.*;
import com.jgoodies.forms.layout.*;

/**
 * @author SHOCKIE
 */
public class RecordingPanel extends JPanel implements TagPositionListener
{
	private Measurement loadedMeasurement;
	private boolean isPlaying;
	private StepwiseFileServerSimulator fileServerSimulator;
	
	public RecordingPanel()
	{
		initComponents();

		measurementInfoLabel.setText("");

		Application application = Application.getInstance();

		try
		{
			fileServerSimulator = new StepwiseFileServerSimulator(application.getPort());
		} catch (IOException e2)
		{
			e2.printStackTrace();
			throw new RuntimeException(e2);
		}

		application.addTagPositionListener(this);

		loadMeasurementButton.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				// open a measurement
				Application application = Application.getInstance();
				JFileChooser jFileChooser = new JFileChooser(application.getDefaultOpenMeasurementFolder());
				int chosenOption = jFileChooser.showOpenDialog(RecordingPanel.this);
				if (chosenOption != JFileChooser.APPROVE_OPTION)
					return;

				// get the file
				File measurementFile = jFileChooser.getSelectedFile();
				try
				{
					loadedMeasurement = application.loadMeasurement(measurementFile);
				} catch (FileNotFoundException e1)
				{
					e1.printStackTrace();
					return;
				}

				int nrOfPositions = loadedMeasurement.getPositions().length;
				measurementInfoLabel.setText(nrOfPositions + " positions");
				currentPositionSlider.setMaximum(nrOfPositions);

				application.startedTracingTag(loadedMeasurement.getLeftTagId());
				application.startedTracingTag(loadedMeasurement.getRightTagId());
				application.startedTracingTag(loadedMeasurement.getFrontTagId());
				application.startedTracingTag(loadedMeasurement.getBackTagId());

				// tagAssignmentPanel.setLoadedMeasurement(loadedMeasurement);
				application.tagAssignmentChanged(TagAssignment.LEFT, loadedMeasurement.getLeftTagId());
				application.tagAssignmentChanged(TagAssignment.RIGHT, loadedMeasurement.getRightTagId());
				application.tagAssignmentChanged(TagAssignment.FRONT, loadedMeasurement.getFrontTagId());
				application.tagAssignmentChanged(TagAssignment.BACK, loadedMeasurement.getBackTagId());

				fileServerSimulator.setMeasurement(loadedMeasurement);
				application.stopListening();
				application.startListening();
				if (!fileServerSimulator.isAlive())
					fileServerSimulator.start();
			}
		});

		currentPositionSlider.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				JSlider slider = (JSlider) e.getSource();
				int currentValue = slider.getValue();
				currentPositionLabel.setText("Positions: (" + currentValue + ")");

				if (!fileServerSimulator.isPlaying())
				{
					fileServerSimulator.pause();
					fileServerSimulator.step(currentValue);
				}
			}
		});

		playPauseButton.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				isPlaying = !isPlaying;
				if (isPlaying)
				{
					playPauseButton.setText("pause");
					fileServerSimulator.play();
				}
				else
				{
					playPauseButton.setText("play");
					fileServerSimulator.pause();
				}
			}
		});

		loopCheckBox.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				fileServerSimulator.setLoop(loopCheckBox.isSelected());
			}
		});
	}

	public void setTagAssigmentPanel(TagAssignmentPanel tagAssignmentPanel)
	{
		recordButton.setAction(new RecordAction(this, tagAssignmentPanel));
	}

	private void initComponents()
	{
		// JFormDesigner - Component initialization - DO NOT MODIFY
		// //GEN-BEGIN:initComponents
		// Generated using JFormDesigner Open Source Project license - unknown
		JPanel replayPanel = new JPanel();
		JLabel loadMeasurementLabel = new JLabel();
		loadMeasurementButton = new JButton();
		currentPositionLabel = new JLabel();
		currentPositionSlider = new JSlider();
		playPauseButton = new JButton();
		loopCheckBox = new JCheckBox();
		JPanel recordingPanel = new JPanel();
		JScrollPane descriptionScrollPane = new JScrollPane();
		descriptionTextArea = new JTextArea();
		JPanel southPanel = new JPanel();
		measurementInfoLabel = new JLabel();
		recordButton = new JButton();
		JSeparator separator = new JSeparator();
		allTagActivitiesPanel = new TagActivityPanel();
		CellConstraints cc = new CellConstraints();

		// ======== this ========
		setName("this");
		setLayout(new FormLayout(ColumnSpec.decodeSpecs("default:grow"), new RowSpec[] { FormFactory.DEFAULT_ROWSPEC,
				FormFactory.LINE_GAP_ROWSPEC, new RowSpec(RowSpec.TOP, Sizes.DEFAULT, FormSpec.DEFAULT_GROW) }));

		// ======== replayPanel ========
		{
			replayPanel.setBorder(new TitledBorder(" Replay measurement "));
			replayPanel.setName("replayPanel");
			replayPanel.setLayout(new FormLayout(new ColumnSpec[] { FormFactory.DEFAULT_COLSPEC,
					FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
					new ColumnSpec(ColumnSpec.FILL, Sizes.DEFAULT, FormSpec.DEFAULT_GROW),
					FormFactory.LABEL_COMPONENT_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC }, new RowSpec[] {
					FormFactory.DEFAULT_ROWSPEC, FormFactory.LINE_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
					FormFactory.LINE_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC }));

			// ---- loadMeasurementLabel ----
			loadMeasurementLabel.setText("Measurement:");
			loadMeasurementLabel.setName("loadMeasurementLabel");
			replayPanel.add(loadMeasurementLabel, cc.xy(1, 1));

			// ---- loadMeasurementButton ----
			loadMeasurementButton.setText("load");
			loadMeasurementButton.setName("loadMeasurementButton");
			replayPanel.add(loadMeasurementButton, cc.xy(5, 1));

			// ---- currentPositionLabel ----
			currentPositionLabel.setText("Positions:");
			currentPositionLabel.setName("currentPositionLabel");
			replayPanel.add(currentPositionLabel, cc.xy(1, 3));

			// ---- currentPositionSlider ----
			currentPositionSlider.setValue(0);
			currentPositionSlider.setName("currentPositionSlider");
			replayPanel.add(currentPositionSlider, cc.xy(3, 3));

			// ---- playPauseButton ----
			playPauseButton.setText("play");
			playPauseButton.setName("playPauseButton");
			replayPanel.add(playPauseButton, cc.xy(5, 3));

			// ---- loopCheckBox ----
			loopCheckBox.setText("loop?");
			loopCheckBox.setSelected(true);
			loopCheckBox.setName("loopCheckBox");
			replayPanel.add(loopCheckBox, cc.xy(5, 5));
		}
		add(replayPanel, cc.xy(1, 1));

		// ======== recordingPanel ========
		{
			recordingPanel.setBorder(new TitledBorder(null, " Measurement recording ", TitledBorder.LEADING,
					TitledBorder.TOP));
			recordingPanel.setName("recordingPanel");
			recordingPanel.setLayout(new FormLayout(ColumnSpec.decodeSpecs("default:grow"), new RowSpec[] {
					new RowSpec("max(default;50dlu)"), FormFactory.LINE_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
					FormFactory.LINE_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.LINE_GAP_ROWSPEC,
					new RowSpec(RowSpec.CENTER, Sizes.DEFAULT, FormSpec.DEFAULT_GROW) }));

			// ======== descriptionScrollPane ========
			{
				descriptionScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
				descriptionScrollPane.setName("descriptionScrollPane");

				// ---- descriptionTextArea ----
				descriptionTextArea.setTabSize(2);
				descriptionTextArea.setName("descriptionTextArea");
				descriptionScrollPane.setViewportView(descriptionTextArea);
			}
			recordingPanel.add(descriptionScrollPane, cc.xywh(1, 1, 1, 1, CellConstraints.FILL, CellConstraints.FILL));

			// ======== southPanel ========
			{
				southPanel.setName("southPanel");
				southPanel.setLayout(new FormLayout(new ColumnSpec[] {
						new ColumnSpec(ColumnSpec.LEFT, Sizes.DEFAULT, FormSpec.DEFAULT_GROW),
						FormFactory.LABEL_COMPONENT_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC }, RowSpec
						.decodeSpecs("default:grow")));

				// ---- measurementInfoLabel ----
				measurementInfoLabel.setText("text");
				measurementInfoLabel.setName("measurementInfoLabel");
				southPanel.add(measurementInfoLabel, cc.xy(1, 1));

				// ---- recordButton ----
				recordButton.setText("text");
				recordButton.setName("recordButton");
				southPanel.add(recordButton, cc.xywh(3, 1, 1, 1, CellConstraints.RIGHT, CellConstraints.DEFAULT));
			}
			recordingPanel.add(southPanel, cc.xy(1, 3));

			// ---- separator ----
			separator.setName("separator");
			recordingPanel.add(separator, cc.xy(1, 5));

			// ---- allTagActivitiesPanel ----
			allTagActivitiesPanel.setName("allTagActivitiesPanel");
			recordingPanel.add(allTagActivitiesPanel, cc.xy(1, 7));
		}
		add(recordingPanel, cc.xy(1, 3));
		// //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY
	// //GEN-BEGIN:variables
	// Generated using JFormDesigner Open Source Project license - unknown
	private JButton loadMeasurementButton;
	private JLabel currentPositionLabel;
	private JSlider currentPositionSlider;
	private JButton playPauseButton;
	private JCheckBox loopCheckBox;
	private JTextArea descriptionTextArea;
	private JLabel measurementInfoLabel;
	private JButton recordButton;
	private TagActivityPanel allTagActivitiesPanel;

	// JFormDesigner - End of variables declaration //GEN-END:variables

	public void clearAllTagPositions()
	{
		this.allTagActivitiesPanel.clearAllTagPositions();
	}

	public void addTagPosition(Position newPosition)
	{
		this.allTagActivitiesPanel.addTagPosition(newPosition);
	}

	public void setInfoText(String text)
	{
		measurementInfoLabel.setText(text);
	}

	public String getDescription()
	{
		return descriptionTextArea.getText();
	}

	public void setLoadedMeasurement(Measurement measurement)
	{
		// set description
		descriptionTextArea.setText(measurement.getDescription());

		this.allTagActivitiesPanel.setTagPositions(measurement.getPositions());
	}
	
	@Override
	public void tagPositionChanged(TagAssignment tagPosition, Position newPosition)
	{
		if (fileServerSimulator.isPlaying())
		{
			int currentPos = fileServerSimulator.getCurrentPosition();
			currentPositionSlider.setValue(currentPos);
		}
	}
	
	@Override
	public void filteredTagPositionChanged(TagAssignment tagAssignment, Position filteredPosition)
	{
		// not implemented
	}

}
